package com.rxyb.auth.config;

import cn.hutool.json.JSONUtil;
import com.rxyb.auth.feign.pojo.user.LoginReq;
import com.rxyb.auth.feign.pojo.user.LoginRsp;
import com.rxyb.auth.feign.user.UserFeignServer;
import com.rxyb.auth.model.SecurityUser;
import com.rxyb.core.respone.R;
import com.rxyb.security.exception.BusiOAuth2Exception;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.switchuser.SwitchUserFilter;

/**
 * @author YJH
 * @version 1.0
 * @description Security 验证
 * @date 2020/5/20  14:19
 */
@Configuration
@EnableWebSecurity
@Slf4j
@Order(90)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    // user信息
    private final UserFeignServer userFeignServer;


    /*TokenEndpoint*/

    /**
     * Creates an instance with the default configuration enabled.
     */
    public SecurityConfiguration(UserFeignServer userFeignServer) {
        this.userFeignServer = userFeignServer;
    }

//    @Bean
//    @Override
//    protected UserDetailsService userDetailsService() {
//        return username -> {
//            if (null == username || username.trim().length() <= 0) {
//                throw new BusiOAuth2Exception("用户名为空");
//            }
//            LoginReq req = new LoginReq();
//            req.setLoginName(username);
//            R<LoginRsp> r = userFeignServer.login(req);
//            log.debug("查询用户:[{}] 登录信息==>[{}]", username, JSONUtil.toJsonStr(r));
//
//            if (!r.ok()) {
//                throw new BusiOAuth2Exception(r.getMsg());
//            }
//            SecurityUser user = new SecurityUser();
//            user.setUsername(username);
//            user.setPassword(r.getData().getLogPwd());
//            return user;
//        };
//    }

    @Bean
    public SwitchUserFilter switchUserFilter(@Qualifier("userDetailsServiceImpl") UserDetailsService userDetailsService) {
        SwitchUserFilter switchUserFilter = new SwitchUserFilter();
        switchUserFilter.setUserDetailsService(userDetailsService);
        switchUserFilter.setTargetUrl("/session");

        return switchUserFilter;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/login").failureUrl("/login-error").permitAll();
        // 退出登录 缓存失效
        http.logout().invalidateHttpSession(true).permitAll();
        http
                .addFilterAfter(switchUserFilter(userDetailsService()), FilterSecurityInterceptor.class);

    }


    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        AuthenticationManager manager = super.authenticationManagerBean();
        return manager;
    }
//
//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.userDetailsService(userDetailsService()).passwordEncoder(new BCryptPasswordEncoder());
//    }
//
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
